<?php
namespace app\admin\controller;

use app\admin\controller\Base;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Request;

class Restore extends Base
{

    public function index($key = '')
    {
        $path = Request::server('DOCUMENT_ROOT') . DIRECTORY_SEPARATOR . 'databackups' . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR;
        if (!is_dir($path)) {
            return show_error('备份不存在', 'admin/tools/backup');
        }
        $tables = $result = [];
        $size   = 0;
        foreach (scandir($path) as $file) {
            if (!in_array($file, ['.', '..']) && pathinfo($file, PATHINFO_EXTENSION) == 'sql') {
                $name = pathinfo($file, PATHINFO_FILENAME);
                if (strpos($name, '-') === false) {
                    $tables[$name][] = '';
                } else {
                    $name               = explode('-', $name);
                    $tables[$name[0]][] = $name[1];
                }
                $size += filesize($path . $file);
            }
        }
        foreach ($tables as $t => $volume) {
            $result[] = $t;
            if ($volumes = array_filter($volume)) {
                sort($volumes);
                foreach ($volumes as $v) {
                    $result[] = $t . '-' . $v;
                }
            }
        }
        Cache::set('backup_restore', $result);
        Cache::set('backup_restore_count', ['files' => count($result), 'size' => $size, 'completed' => 0]);
        return show_success("数据整理完毕，正在恢复 $result[0] 数据表，请勿关闭浏览器...", url('install/restore/restoring', ['key' => $key]), '', 0);
    }

    public function restoring($key = '')
    {
        $path = Request::server('DOCUMENT_ROOT') . DIRECTORY_SEPARATOR . 'databackups' . DIRECTORY_SEPARATOR . $key . DIRECTORY_SEPARATOR;
        if (!is_dir($path)) {
            return show_error('备份不存在');
        }
        if ($restore = Cache::get('backup_restore')) {
            $file  = $path . $restore[0] . '.sql';
            $count = Cache::get('backup_restore_count');
            $count['completed'] += filesize($file);
            $sql = file_get_contents($file);
            $this->run_sql($sql);
            if ($restore = array_splice($restore, 1)) {
                Cache::set('backup_restore', $restore);
                Cache::set('backup_restore_count', $count);
                $progress = round($count['completed'] / $count['size'], 4) * 100;
                return show_success('正在恢复 ' . $restore[0] . ' 数据表，已完成：<b style="color:#f00">' . $progress . '</b> %！', url('install/restore/restoring', ['key' => $key]), '', 0);
            }
            Cache::rm('backup_restore_count');
            Cache::rm('backup_restore');
        }
        return show_success('备份恢复成功！', 'admin/tools/backup');
    }

    private function run_sql($sql = '')
    {
        if (!$sql) {
            return false;
        }
        $i = $error = 0;
        foreach ($this->_split_sql(str_replace(
            [' {prefix}', ' prefix_', ' `prefix_'],
            [' ' . config('database.prefix'), ' ' . config('database.prefix'), ' `' . config('database.prefix')],
            $sql)) as $sql) {
            try {
                $result = Db::execute($sql);
                if ($result !== false) {
                    $i++;
                }
            } catch (\Exception $e) {
                $error++;
            }
        }
        return ['success' => $i, 'error' => $error];
    }

    private function _split_sql($sql)
    {
        $sql          = str_replace([PHP_EOL, "\r"], "\n", $sql);
        $ret          = [];
        $num          = 0;
        $queriesarray = explode(";\n", trim($sql));
        unset($sql);
        foreach ($queriesarray as $query) {
            $queries   = explode("\n", trim($query));
            $ret[$num] = '';
            foreach ($queries as $query) {
                $ret[$num] .= substr($query, 0, 1) == "#" ? null : $query;
            }
            $num++;
        }
        return ($ret);
    }

}
